/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package cn.yr.system.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.yr.common.core.constant.CacheKeyConstants;
import cn.yr.common.core.domain.dto.SysUserDto;
import cn.yr.common.core.domain.entity.SysUser;
import cn.yr.common.core.domain.vo.LoginUserVo;
import cn.yr.common.core.manager.AuthCacheManager;
import cn.yr.common.core.manager.AuthUserManager;
import cn.yr.common.core.utils.jwt.JwtUtil;
import cn.yr.common.exception.ret.Ret;
import cn.yr.system.service.ILoginService;
import cn.yr.system.service.ISysUserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;

/**
 * @title: SysLoginController
 * @description: 登录相关
 * @author: Lang 1102076808@qq.com
 * @date: 2020/6/18 23:36
 */
@RestController
public class LoginWebController {

    @Resource
    private ILoginService loginService;

    @Resource
    private AuthCacheManager authCacheManager;

    @Resource
    private AuthUserManager authUserManager;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private ISysUserService sysUserService;

    /**
     * 后台登录
     */
    @RequestMapping("/login")
    public Ret login(@RequestBody LoginUserVo loginUserVo) {
        /** 登录认证*/
        if (!validCaptcha(loginUserVo.getCaptcha(), loginUserVo.getUuid())) {
            return Ret.error("验证码错误");
        }
        return loginData(loginUserVo);
    }

    /**
     * app登录
     */
    @RequestMapping("/appLogin")
    public Ret loginApp(@RequestBody LoginUserVo loginUserVo) {
        return loginData(loginUserVo);
    }

    private Ret loginData(LoginUserVo loginUserVo) {
        SysUser user = loginService.getByUsername(loginUserVo.getUsername());
        if (ObjectUtil.isEmpty(user)) {
            return Ret.error("用户不存在");
        }
        String password = loginService.generatePassword(loginUserVo.getPassword(), user.getSalt());
        if (!StrUtil.equals(password, user.getPassword())) {
            return Ret.error("密码错误");
        }
        user.setPassword("");
        user.setSalt("");
        /** 缓存用户信息与权限*/
        SysUserDto sysUserDto = loginService.initUser(user);
        authCacheManager.putUser(user.getUserId().toString(), sysUserDto);
        /** 返回token*/
        String token = JwtUtil.generateToken(user.getUserId().toString());
        Map<Object, Object> map = MapUtil.builder().put("userInfo", user).put("token", token).map();
        return Ret.success(map);

    }

    @RequestMapping("/resetPassword")
    public Ret resetPassword(@NotNull String username, @NotNull String password){
        String salt = loginService.generateSalt();
        String generatePassword = loginService.generatePassword(password, salt);
        SysUser sysUser = loginService.getByUsername(username);
        if(ObjectUtil.isEmpty(sysUser)){
            return Ret.error("用户名不存在");
        }
        sysUser.setPassword(generatePassword);
        sysUser.setSalt(salt);
        sysUserService.updateById(sysUser);
        return Ret.success("修改成功");
    }


    @RequestMapping("getInfo")
    public Ret getInfo() {
        SysUserDto user = authUserManager.getUser();
        return Ret.success(user);
    }

    /**
     * 退出
     */
    @PostMapping("/logout")
    public Ret logout() {
        return Ret.success();
    }


    /**
     * @description 校验验证码
     * @author Lang
     * @date 2020/7/18 17:57
     */
    private boolean validCaptcha(String code, String uuid) {
        String redisCode = (String) redisTemplate.opsForValue().get(CacheKeyConstants.CAPTCHA_KEY + uuid);
        return StrUtil.equalsIgnoreCase(redisCode, code);
    }

    /**
     * 验证码
     * @return
     * @throws IOException
     */
    @RequestMapping("/captcha")
    public Ret captcha() {
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(300, 100, 4, 4);
        String uuid = IdUtil.fastSimpleUUID();
        String imageBase64 = captcha.getImageBase64();
        redisTemplate.opsForValue().set(CacheKeyConstants.CAPTCHA_KEY + uuid, captcha.getCode(), Duration.ofMinutes(5));
        Map<String, String> map = MapUtil.builder("uuid", uuid).put("img", imageBase64).map();
        return Ret.success(map);
    }

}
